package cc.bukkitPlugin.banitem.command;

import java.util.Map;

import org.bukkit.Material;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
import org.bukkit.inventory.ItemStack;

import cc.bukkitPlugin.banitem.BanItemEnume.ListType;
import cc.bukkitPlugin.banitem.BanItemEnume.OperateType;
import cc.bukkitPlugin.banitem.check.SimpleWorld;
import cc.bukkitPlugin.banitem.check.WorldTypeItem;
import cc.bukkitPlugin.banitem.check.nbtvalue.ExpressNBTValue;
import cc.bukkitPlugin.banitem.command.analyse.AnalyseResult;
import cc.bukkitPlugin.banitem.command.analyse.ParamDamage;
import cc.bukkitPlugin.banitem.command.analyse.ParamItem;
import cc.bukkitPlugin.banitem.command.analyse.ParamListType;
import cc.bukkitPlugin.banitem.command.analyse.ParamNBTLabel;
import cc.bukkitPlugin.banitem.command.analyse.ParamNBTValue;
import cc.bukkitPlugin.banitem.command.analyse.ParamWorld;
import cc.bukkitPlugin.banitem.manager.ItemManager;
import cc.bukkitPlugin.util.nbt.NBTUtil;

public abstract class ACommandListOp extends AParamCommand{

    private final OperateType mOpType;

    public ACommandListOp(CommandExc pExector,OperateType pOpType){
        super(pExector,pOpType.name().toLowerCase());
        this.mOpType=pOpType;
        // 初始化参数模块
        this.registerParam(ParamListType.class);
        this.registerParam(ParamItem.class);
        this.registerParam(ParamDamage.class);
        this.registerParam(ParamNBTLabel.class);
        this.registerParam(ParamNBTValue.class);
        this.registerParam(ParamWorld.class);
    }

    @Override
    public boolean execute(CommandSender pSender,String pLabel,String[] pArgs){
        if(!pSender.hasPermission(this.mPluginName+".item."+this.getCommandLabel()))
            return noPermission(pSender);
        //一级子命令检查
        if(pArgs.length==1&&pArgs[0].equalsIgnoreCase("help"))
            return help(pSender,pLabel);
        //参数建立
        AnalyseResult tCmdParam=new AnalyseResult();
        if(pArgs.length>0){
            tCmdParam=this.mAnalyseMan.buildParam(pSender,this,pArgs);
            if(tCmdParam.mBuildError)
                return send(pSender,tCmdParam.mBuildErrorMsg);
        }
        //查看生成的参数结果是否有效
        if(tCmdParam.mListType==null){ //没有指定操作列表
            tCmdParam.mListType=ListType.BAN;
        }
        ItemStack itemInHand=null;
        if(pSender instanceof Player){
            Player tPlayer=(Player)pSender;
            itemInHand=tPlayer.getItemInHand();
            if(itemInHand==null||itemInHand.getType()==Material.AIR)
                itemInHand=null;
        }
        if(tCmdParam.mItem==null){ //没有指定物品
            if(itemInHand==null)
                return send(pSender,"&c未指定物品参数[i,item],且手上没有拿着东西");
            tCmdParam.mItem=itemInHand.getType();
        }
        if(tCmdParam.mDamage==null){ //没有指定damage
            if(itemInHand==null){
                if(this.mOpType!=OperateType.REMOVE){
                    return send(pSender,"&c未指定子id参数[d,damage],且手上没有拿着东西");
                }
            }else{
                tCmdParam.mDamage=itemInHand.getDurability();
            }
        }
        if(tCmdParam.mNBTLabel==null){ //没有指定NBT标签
            if(tCmdParam.mNBTValue!=null)
                return send(pSender,"&c由于未设置NBT标签参数[nl,nbtlabel],NBT值参数[nv,nbtvalue]指定无效");
        }else{
            if(tCmdParam.mListType==ListType.NBT) //NBT检查列表不能指定NBT检查参数
                return send(pSender,"&cNBT检查列表不能指定NBT参数");
            if(tCmdParam.mNBTValue==null&&this.mOpType!=OperateType.REMOVE){
                Map<String,Object> tNBTContents=NBTUtil.getNBTTagMapFromItem(itemInHand);
                Object tNBTNode=(tNBTContents==null?null:tNBTContents.get(tCmdParam.mNBTLabel));
                if(tNBTNode==null)
                    return send(pSender,"&c物品无("+tCmdParam.mNBTLabel+")这个NBT标签,必须手动指定NBT值参数[nv,nbtvalue]");
                tCmdParam.mNBTValue=NBTUtil.getNBTSimpleJson(tNBTNode);
            }
        }
        tCmdParam.mOperate=this.mOpType;
        if(tCmdParam.mWorld.equals(SimpleWorld.defaultWorld)&&pSender instanceof Player)
            tCmdParam.mWorld=SimpleWorld.create(((Player)pSender).getWorld().getName());
        //尝试参数要求的动作
        AnalyseResult result;
        WorldTypeItem tWorldTypeItem=this.mPlugin.getManager(ItemManager.class).getWorldTypeItem(tCmdParam.mWorld,tCmdParam.mListType);
        switch(tCmdParam.mOperate){
        case ADD:
            if(tCmdParam.mNBTValue!=null&&tCmdParam.mNBTValue.contains("%value%")){
                if(!ExpressNBTValue.isValidExpress(tCmdParam.mNBTValue,pSender,true))
                    return true;
            }
            tWorldTypeItem.add(pSender,tCmdParam);
            break;
        case CHECK:
            result=tWorldTypeItem.check(pSender,tCmdParam);
            if(result.mFind){
                send(pSender,"命令参数中的物品与以下配置项相同");
                result.sendInfo(pSender);
            }else{
                send(pSender,"&c未发现与以下命令参数物品配置相同的配置:");
                result.sendInfo(pSender,"&c  |");
                send(pSender,"&c"+result.mUnFitReason);
            }
            break;
        case REMOVE:
            tWorldTypeItem.remove(pSender,tCmdParam);
            break;
        case TEST:
            result=tWorldTypeItem.test(pSender,tCmdParam);
            if(result.mFind){
                send(pSender,"命令参数中的物品配置符合以下配置项");
                result.sendInfo(pSender);
            }else{
                send(pSender,"&c未发现适合以下命令参数物品配置的配置");
                result.sendInfo(pSender,"&c  |");
                send(pSender,"&c"+result.mUnFitReason);
            }
            break;
        }
        return true;
    }

    @Override
    public int getMaxArgumentLength(String pLabel){
        return this.getAllowParam().size();
    }

}
